package data;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import presentation.MainScreen;
import presentation.PlayPanel;

import logic.Action;
import logic.SimonSays;

import com.leapmotion.leap.Gesture;
import com.leapmotion.leap.GestureList;

public class LeapMotionSimonSays {
	private Thread leapThread;
	private LeapMotionInterface leapInterface;
	
	//private
	public SimonSays game;
	private Map<Gesture.Type, Action> gestureMapping;
	private MainScreen Ps;
	private int NUMBER_OF_PLAYERS;
	
	//number of points a player gets when reproducing the correct gesture pattern
	private int NUMBER_OF_POINTS = 50;
	
	//start-score is zero (we assume here that there are only 2 players)
	private List<Integer> scores = new ArrayList<Integer>();
	
	
	public LeapMotionSimonSays(List<Gesture.Type> gestureTypes) {
		leapInterface = new LeapMotionInterface(gestureTypes);
		/* Note: thread will be running but LeapMotionInterface 
		 * will wait for a .toggle() to do anything useful. */
		leapThread = new Thread(leapInterface);
		
		gestureMapping = new HashMap<Gesture.Type, Action>();
		
		/* Associate every allowed Leap Motion gesture type with the action to be performed by the player */
		for(int i = 0; i < gestureTypes.size(); i++) {
			gestureMapping.put(gestureTypes.get(i), new Action(i));
		}		
		
		/* Provide the actions to the game logic */
		game = new SimonSays(gestureMapping.values());
	}

	
	public void start(int playerCount) {
		NUMBER_OF_PLAYERS = playerCount;
		//initialize score
		for(int i = 0; i < playerCount; i++){
			scores.add(-NUMBER_OF_POINTS);
		}
		/* Enable event listening from the LeapMotion */
		leapInterface.toggle();
		try {
			game.startGame(playerCount);
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		
		while(game.isRunning()) {
			/* Get current player and action from the game logic */
			int currentPlayer = game.getCurrentPlayer();
			Action currentAction = game.getCurrentAction();

			/* Display that info on the presentation level */
			displayInfo(currentPlayer, currentAction, scores.get(currentPlayer), game.getNewGesture(), game.getGestureIndex());
			/* Keep polling the LeapMotionInterface until a gesture is recognised
			 * and input that action into the game logic */
			Action recentAction = null;
			while(recentAction == null) {
				List<Gesture> gestures = leapInterface.mostRecentGestures();
				if ((!gestures.isEmpty() && (leapInterface.hasBufferChanged()))) {
					// Hack, assumes buffer size is 1
					System.out.println(gestures.toString() + " " + gestures.get(0).type());
					recentAction = gestureMapping.get(gestures.get(0).type());
					game.inputAction(recentAction);
					try {
						TimeUnit.SECONDS.sleep(1);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
		leapInterface.removeListener();
	}
	
	public void displayInfo(int player, Action action, int score, boolean newGesture, int indexGesture) {
		System.out.println("Player" + player + "'s turn, action required: " + action.type);
		// give the player and action to the GUI
		scores.set(player, score + NUMBER_OF_POINTS);
		Ps.ChangeGesture(action.type, player, (score + NUMBER_OF_POINTS), newGesture, indexGesture);
	}
	
	//this is needed to stop the game from the playscreen 
	public void stopGame(){
		game.stopGame();
	}
	
	public static void main(String[] args) {
		Gesture.Type swipe = Gesture.Type.TYPE_SWIPE;
		List<Gesture.Type> gestures = new ArrayList<Gesture.Type>();
		gestures.add(swipe);
		LeapMotionSimonSays game = new LeapMotionSimonSays(gestures);
		game.start(1);
	}
	

	
}
